#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_FILENAME_LENGTH 256

// 定义链表节点结构体及Node类型
typedef struct node 
{
    char *filename;
    struct node *next;
} *Node;

// 创建新节点的函数
Node create_node(const char *filename) 
{
    Node new_node = (Node)malloc(sizeof(struct node));
    if (new_node != NULL) {
        new_node->filename = (char *)malloc(strlen(filename) + 1);
        if (new_node->filename != NULL) 
        {
            strcpy(new_node->filename, filename);
        } 
        else 
        {
            perror("内存分配失败");
            free(new_node);  // 如果分配filename失败，释放new_node
            new_node = NULL;
        }
        new_node->next = NULL;
    }
    return new_node;
}

// 销毁循环链表的函数
void destroy_list(Node head) 
{
    if (head == NULL) 
    {
        return; // 如果头节点为空，直接返回
    }

    Node current = head->next; // 从头节点的下一个节点开始
    if (current == NULL) 
    {
        free(head); // 如果没有数据节点，释放头节点
        return;
    }

    // 使用while循环遍历并释放链表节点
    while (current->next != head) 
    {
        Node next = current->next; // 保存下一个节点的地址
        free(current->filename);   // 释放当前节点的filename
        free(current);             // 释放当前节点
        current = next;            // 移动到下一个节点
    }

    // 释放循环链表的最后一个节点和头节点
    free(current->filename); // 释放最后一个节点的filename
    free(current);           // 释放最后一个节点
    free(head);              // 释放头节点
}

// 从文件中加载图片名称到循环链表
void load_pictures_from_file(Node *head, const char *filename) 
{
    FILE *file = fopen(filename, "r");
    if (!file) 
    {
        perror("无法打开文件");
        return;
    }

    char buffer[MAX_FILENAME_LENGTH];
    Node tail = NULL; // 用于记录链表的最后一个节点

    // 尝试读取第一行
    if (fgets(buffer, MAX_FILENAME_LENGTH, file)) 
    {
        buffer[strcspn(buffer, "\n")] = 0; // 去除换行符
        *head = create_node(buffer); // 创建头节点
        if (*head == NULL) 
        {
            fclose(file);
            return;
        }
        tail = *head; // 将tail指向头节点
    } 
    else {
        // 如果文件为空，关闭文件并返回
        fclose(file);
        return;
    }

    // 继续读取剩余的行
    while (fgets(buffer, MAX_FILENAME_LENGTH, file)) 
    {
        buffer[strcspn(buffer, "\n")] = 0; // 去除换行符
        Node new_node = create_node(buffer);
        if (new_node == NULL) 
        {
            fprintf(stderr, "内存分配失败。\n");
            continue;
        }
        tail->next = new_node; // 将新节点链接到链表末尾
        tail = new_node; // 更新tail为新节点
    }

    // 形成循环链表
    if (tail != NULL) 
    {
        tail->next = *head;
    }
    fclose(file);
}
// 显示循环链表中的所有图片
void list_pictures(Node head) 
{
    if (head == NULL || head->next == NULL) 
    {
        printf("链表为空。\n");
        return;
    }

    Node current = head; // 从链表的第一个数据节点开始
    do 
    {
        printf("%s\n", current->filename);
        current = current->next;
    } while (current != head); // 循环直到再次到达第一个数据节点
}

// 主函数
int main() 
{
    const char *filename = "pictures.txt";
    Node head = NULL; // 初始化头节点为NULL

    // 从文件加载图片名称
    printf("从文件加载图片名称...\n");
    load_pictures_from_file(&head, filename);

    // 显示所有图片
    printf("当前链表中的图片名称：\n");
    list_pictures(head);

    // 销毁链表释放内存
    printf("销毁链表释放内存...\n");
    destroy_list(head);

    return 0;
}